package com.benew.ntt.xseval.utils

import android.annotation.SuppressLint
import android.os.Build
import android.text.TextUtils
import android.util.Log
import com.benew.ntt.evaluate.constant.EvalConst
import com.benew.ntt.evaluate.sdk.EvalSDKConfig
import com.benew.ntt.evaluate.sdk.EvalSDKType
import com.benew.ntt.xseval.constant.XSEvalConst
import com.benew.ntt.xseval.sdk.XSEvalSDK
import com.blankj.utilcode.util.GsonUtils
import com.blankj.utilcode.util.NetworkUtils
import com.constraint.CoreProvideTypeEnum
import com.google.gson.reflect.TypeToken
import com.ntt.core.nlogger.NLogger
import com.tencent.mmkv.MMKV
import com.xs.SingEngine
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL

object AuthUtils {
    val TAG = javaClass.simpleName

    //证书过期时间
    private var mExpire = 0.0

    private var mXSEvalSDK: XSEvalSDK? = null

    fun init(xsEvalSDK: XSEvalSDK?) {
        mXSEvalSDK = xsEvalSDK
    }

    /**
     * 刷新WarrantId
     */
    fun refreshWarrantId() {
        val currentTimeMillis = System.currentTimeMillis()
        NLogger.d(
            TAG, "刷新WarrantId", "currentTimeMillis:$currentTimeMillis",
            "mExpire:$mExpire",
            EvalConst.getWarrantIdTime()
        )
        if (currentTimeMillis >= mExpire * 1000 - EvalConst.getWarrantIdTime()) { //WarrantId过期
            getWarrantId()
        }
    }

    /**
     * 获取评测鉴权信息
     */
    @SuppressLint("MissingPermission")
    fun getWarrantId() {
        if (EvalConst.config == null || !NetworkUtils.isConnected()) {
            return
        }
        Thread {
            var conn: HttpURLConnection? = null
            try {

                val toJson = GsonUtils.toJson(EvalConst.config)
                NLogger.d(TAG, "获取评测鉴权信息",toJson )
                Log.e(TAG, "getWarrantId: $toJson")
                if (EvalConst.config?.getDeviceId().isNullOrBlank()
                    || EvalConst.config?.token.isNullOrBlank()
                ) {
                    NLogger.d(TAG,"deviceId或者token为空")
                    return@Thread
                }
                val requestUrl =
                    EvalConst.config?.host + "resources-app/voice/token?deviceId=" + EvalConst.config?.getDeviceId()
                val url = URL(requestUrl)
                conn = url.openConnection() as HttpURLConnection
                conn.setRequestProperty("Authorization", "Bearer " + EvalConst.config?.token)

                conn.connectTimeout = 5000
                conn.headerFields
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
                    conn.requestMethod = "GET"
                }
                NLogger.d(
                    TAG,
                    "获取评测鉴权请求$requestUrl"
                )
                // 判断请求Url是否成功
                if (conn.responseCode == 200) {

                    val iStream: InputStream = conn.inputStream

                    BufferedReader(InputStreamReader(iStream)).use { reader ->
                        val readText = reader.readText()
                        NLogger.d(
                            TAG,
                            "评测鉴权返回response=$readText"
                        )
                        if (readText.isNotBlank()) {
                            val response = GsonUtils.fromJson<Map<String, Any?>>(
                                readText,
                                object : TypeToken<Map<String, Any?>>() {}.type
                            )
                            val data = response?.get("data") as Map<String, Any>
                            saveWarrantIdEntity(data)
                            setAuthInfoData(data)
                        }
                    }
                } else {
                    NLogger.d(
                        TAG,
                        "获取评测鉴权失败",
                        conn.responseCode,
                        conn.responseMessage
                    )
                }
            } catch (e: Exception) {
                NLogger.d(
                    TAG,
                    "获取评测鉴权失败",
                    e.message
                )
            } finally {
                conn?.disconnect()
            }
        }.start()
    }

    /**
     * 保存鉴权信息
     *
     * @param data
     */
    private fun saveWarrantIdEntity(data: Map<String, Any?>?) {
        val json = if (data.isNullOrEmpty()) {
            ""
        } else {
            GsonUtils.toJson(data)
        }
        Log.d(TAG, "保存鉴权信息: $json")
        NLogger.d(TAG, "保存鉴权信息: $json")

        MMKVUtil.getInstance(
            XSEvalConst.MMKV_FILE_EVALUATE,
            XSEvalConst.MMKV_DIR,
            MMKV.MULTI_PROCESS_MODE
        ).encode(XSEvalConst.MMKV_KEY_EVALUATE_WARRANT_ID, json)
    }

    /**
     * 获取本地鉴权信息
     */
    private fun getWarrantIdEntity(): String {
        return MMKVUtil.getInstance(
            XSEvalConst.MMKV_FILE_EVALUATE,
            XSEvalConst.MMKV_DIR,
            MMKV.MULTI_PROCESS_MODE
        ).decodeString(XSEvalConst.MMKV_KEY_EVALUATE_WARRANT_ID, "")
    }

    /**
     * 评测设置鉴权信息
     */
    fun setAuthInfo() {
        try {
            val json = getWarrantIdEntity()
            NLogger.d(
                TAG,
                "setAuthInfo json:$json"
            )
            if (!TextUtils.isEmpty(json)) {
                val data = GsonUtils.fromJson<Map<String, Any>>(
                    json,
                    object : TypeToken<Map<String?, Any?>?>() {}.type
                )
                setAuthInfoData(data)
            } else {
                getWarrantId()
            }
        } catch (e: Exception) {
            NLogger.d(
                TAG,
                "setAuthInfo 失败转成离线:" + e.message
            )
            mXSEvalSDK?.getSingEngine()?.apply {
                this.setServerType(CoreProvideTypeEnum.NATIVE)
                setServerInfoType(this, true)
                this.setAuthInfo(null, 0)
            }
        }
    }

    /**
     * 评测设置鉴权信息
     */
    private fun setAuthInfoData(data: Map<String, Any?>?) {
        NLogger.d(
            TAG, "setAuthInfo",
        )
        data?.let {
            mXSEvalSDK?.getSingEngine()?.apply {
                val warrantId = it["token"] as String?
                mExpire = it["expire"] as Double? ?: 0.0
                this.setAuthInfo(warrantId, mExpire.toLong())
                setServerInfoType(this, false)
                NLogger.d(
                    TAG,
                    "评测设置鉴权信息：warrantId=$warrantId;expire=$mExpire"
                )
            }
        }
    }

    /**
     * 设置评测类型
     * @param forceNative 强制离线
     */
    fun setServerInfoType(
        singEngine: SingEngine?,
        forceNative: Boolean
    ) {
        when (EvalConst.config?.evalSDKType) {
            EvalSDKType.CLOUD -> {
                singEngine?.setServerType(CoreProvideTypeEnum.CLOUD)
                NLogger.d(TAG, "使用CLOUD")
            }
            EvalSDKType.NATIVE -> {
                singEngine?.setServerType(CoreProvideTypeEnum.NATIVE)
                NLogger.d(TAG, "使用NATIVE")
            }
            EvalSDKType.AUTO -> {
                singEngine?.setServerType(CoreProvideTypeEnum.AUTO)
                NLogger.d(TAG, "使用AUTO")
            }
            else -> {
                //如果是混合模式，那就判断是不是强制只用离线
                if (forceNative) {
                    singEngine?.setServerType(CoreProvideTypeEnum.NATIVE)
                    NLogger.d(TAG, "强制使用NATIVE")
                } else {
                    if (NetworkUtils.isConnected()) {
                        singEngine?.setServerType(CoreProvideTypeEnum.CLOUD)
                        NLogger.d(TAG, "网络连接了，使用CLOUD")
                    } else {
                        singEngine?.setServerType(CoreProvideTypeEnum.AUTO)
                        NLogger.d(TAG, "网络断开了，使用AUTO")
                    }
                }
            }
        }
    }

}